package com.ld.control.business.process.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ld.control.business.data.service.TemporaryMapService;
import com.ld.control.business.equipment.service.EquipmentService;
import com.ld.control.business.equipment.vo.resp.EquipmentRespVo;
import com.ld.control.business.process.mapper.ProcessNodeExampleMapper;
import com.ld.control.business.process.mapper.ProcessNodeParamExampleMapper;
import com.ld.control.business.process.model.*;
import com.ld.control.business.process.model.ext.ProcessNodeExampleInfoExt;
import com.ld.control.business.process.service.ProcessExampleService;
import com.ld.control.business.process.service.ProcessNodeExampleRunningService;
import com.ld.control.business.process.service.ProcessNodeExampleService;
import com.ld.control.business.process.service.ProcessNodeParamExampleService;
import com.ld.control.business.process.vo.internal.DataExt1Vo;
import com.ld.control.business.process.vo.resp.*;
import com.ld.control.business.queue.service.PendingNodeQueueService;
import com.ld.control.business.record.service.MessageNoticeRecordService;
import com.ld.control.business.sample.service.SampleService;
import com.ld.control.business.task.model.SubTaskExampleModel;
import com.ld.control.business.task.model.TaskExampleModel;
import com.ld.control.business.task.service.SubTaskExampleService;
import com.ld.control.business.task.service.TaskExampleService;
import com.ld.control.business.variable.model.VariableExampleModel;
import com.ld.control.business.variable.model.VariableModel;
import com.ld.control.business.variable.service.VariableExampleService;
import com.ld.control.business.variable.service.VariableService;
import com.ld.control.business.variable.vo.resp.VariableExampleValueResp;
import com.ld.control.common.NodeParamConstant;
import com.ld.control.exception.BusinessException;
import com.ld.control.sysenum.MethodParamTypeEnum;
import com.ld.control.sysenum.ProcessNodeNameEnum;
import com.ld.control.sysenum.TaskStatusEnum;
import com.ld.control.utils.CommonUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.*;

/**
 * <p>
 * 任务流程节点实例表 服务实现类
 * </p>
 *
 * @author wangfeng
 * @since 2024-05-21
 */
@Slf4j
@Service
public class ProcessNodeExampleServiceImpl extends ServiceImpl<ProcessNodeExampleMapper, ProcessNodeExampleModel> implements ProcessNodeExampleService {

    @Autowired
    @Qualifier("customThreadPool")
    private ThreadPoolTaskExecutor taskExecutor;

    @Autowired
    private TemporaryMapService temporaryMapService;

    @Autowired
    private ProcessNodeExampleMapper processNodeExampleMapper;

    @Autowired
    private ProcessNodeExampleService processNodeExampleService;

    @Autowired
    private ProcessExampleService processExampleService;

    @Autowired
    private ProcessNodeExampleRunningService processNodeExampleRunningService;

    @Autowired
    private SubTaskExampleService subTaskExampleService;

    @Autowired
    private TaskExampleService taskExampleService;

    @Autowired
    private PendingNodeQueueService pendingNodeQueueService;

    @Autowired
    private ProcessNodeParamExampleMapper processNodeParamExampleMapper;

    @Autowired
    private ProcessNodeParamExampleService processNodeParamExampleService;

    @Autowired
    private MessageNoticeRecordService messageNoticeRecordService;

    @Autowired
    private VariableExampleService variableExampleService;

    @Autowired
    private VariableService variableService;

    @Autowired
    private EquipmentService equipmentService;

    @Override
    public ProcessNodeExampleModel getStartNodeInfo(Long processExampleId) {
        QueryWrapper<ProcessNodeExampleModel> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(ProcessNodeExampleModel.PROCESS_EXAMPLE_ID, processExampleId);
        queryWrapper.eq(ProcessNodeExampleModel.NODE_NAME, ProcessNodeNameEnum.START_NODE.getNodeName());
        queryWrapper.eq(ProcessNodeExampleModel.NODE_FLAG, 0);
        ProcessNodeExampleModel processNodeExampleModel = processNodeExampleMapper.selectOne(queryWrapper);
        if (ObjectUtils.isEmpty(processNodeExampleModel)) {
            throw new BusinessException("未找到开始节点");
        }
        return processNodeExampleModel;
    }

    @Override
    public void runNextNode(Long processNodeExampleId) {
        // 查询当前节点的下一个节点信息
        List<ProcessNodeExampleModel> nextNodeList = getNextNodes(processNodeExampleId);
        log.info("runNextNode_nextNodeList:{}->{}", processNodeExampleId, JSONObject.toJSONString(nextNodeList));
        for (ProcessNodeExampleModel nextNode : nextNodeList) {
            //taskExecutor.execute(() -> {
            syncRunNode(nextNode);
            //});
        }
    }

    @Override
    public void updateNodeStatus(Long processNodeExampleId, Integer status) {
        ProcessNodeExampleModel processNodeExampleModel = processNodeExampleMapper.selectById(processNodeExampleId);
        processNodeExampleModel.setId(processNodeExampleId);
        processNodeExampleModel.setStatus(status);
        processNodeExampleModel.setUpdateTime(new Date());
        if (status == TaskStatusEnum.RUNNING.getStatus()) {
            processNodeExampleModel.setStartTime(new Date());
        }
        if (status == TaskStatusEnum.SUCCESS.getStatus()) {
            processNodeExampleModel.setEndTime(new Date());
        }
        processNodeExampleMapper.updateById(processNodeExampleModel);
    }

    @Override
    public ProcessNodeExampleInfoExt getProcessNodeExampleModelExt(Long processNodeExampleId) {
        ProcessNodeExampleInfoExt processNodeExampleInfoExt = new ProcessNodeExampleInfoExt();
        // 查询流程节点的实例详情
        ProcessNodeExampleModel processNodeExampleModel = processNodeExampleMapper.selectById(processNodeExampleId);
        Long processExampleId = processNodeExampleModel.getProcessExampleId();
        BeanUtils.copyProperties(processNodeExampleModel, processNodeExampleInfoExt);
        ProcessExampleModel processExampleModel = processExampleService.getById(processExampleId);
        processNodeExampleInfoExt.setProcessExampleModel(processExampleModel);
        // 查询子任务详情
        Long subTaskExampleId = processExampleModel.getSubTaskExampleId();
        if (subTaskExampleId != null) {
            SubTaskExampleModel subTaskExampleModel = subTaskExampleService.getById(subTaskExampleId);
            processNodeExampleInfoExt.setSubTaskExampleModel(subTaskExampleModel);
        }
        // 查询任务详情
        TaskExampleModel taskExampleModel = taskExampleService.getById(processExampleModel.getTaskExampleId());
        processNodeExampleInfoExt.setTaskExampleModel(taskExampleModel);
        return processNodeExampleInfoExt;
    }

    @Override
    public Map<String, NodeExtInfo> getNoteExtInfoMap(Long processExampleId) {
        Map<String, NodeExtInfo> nodeExtInfoMap = new HashMap<>();
        List<ProcessNodeExampleModel> processNodeExampleModels = processNodeExampleMapper.selectListByProcessExampleId(processExampleId);
        for (ProcessNodeExampleModel processNodeExampleModel : processNodeExampleModels) {
            NodeExtInfo nodeExtInfo = new NodeExtInfo();
            String sourceNodeId = processNodeExampleModel.getSourceNodeId();
            Integer status = processNodeExampleModel.getStatus();
            nodeExtInfo.setColor(TaskStatusEnum.getColor(status));
            nodeExtInfo.setNodeExampleId(processNodeExampleModel.getId());
            nodeExtInfoMap.put(sourceNodeId, nodeExtInfo);
        }
        return nodeExtInfoMap;
    }

    @Override
    public ProcessNodeExampleDetailsResp getProcessNodeExampleDetails(Long processNodeExampleId) {
        ProcessNodeExampleDetailsResp processNodeExampleDetailsResp = new ProcessNodeExampleDetailsResp();
        ProcessNodeExampleModel processNodeExampleModel = processNodeExampleMapper.selectById(processNodeExampleId);
        BeanUtils.copyProperties(processNodeExampleModel, processNodeExampleDetailsResp);

        Map<String, Object> paramMap = new HashMap<>(64);
        List<ProcessNodeParamExampleRespVo> nodeParamExampleRespVoList = new ArrayList<>();
        // 非设备节点
        //if (processNodeExampleDetailsResp.getNodeFlag() == CommonConstant.NODE_FLAG.EQUIPMENT) {
        List<ProcessNodeParamExampleModel> processNodeParamExampleModels = processNodeParamExampleMapper.selectListByProcessNodeExampleId(processNodeExampleId);
        ProcessNodeParamExampleRespVo processNodeParamExampleRespVo = null;
        for (ProcessNodeParamExampleModel processNodeParamExampleModel : processNodeParamExampleModels) {
            processNodeParamExampleRespVo = new ProcessNodeParamExampleRespVo();
            BeanUtils.copyProperties(processNodeParamExampleModel, processNodeParamExampleRespVo);
            nodeParamExampleRespVoList.add(processNodeParamExampleRespVo);
            paramMap.put(processNodeParamExampleModel.getName(), processNodeParamExampleModel.getValue());
        }
        //}
        // 设备节点
       /* if (processNodeExampleDetailsResp.getNodeFlag() == CommonConstant.NODE_FLAG.EQUIPMENT) {
            QueryWrapper<ProcessNodeExampleRunningModel> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq(ProcessNodeExampleRunningModel.PROCESS_NODE_EXAMPLE_ID, processNodeExampleId);
            ProcessNodeExampleRunningModel processNodeExampleRunningModel = processNodeExampleRunningMapper.selectOne(queryWrapper);
            List<ProcessNodeExampleRunningParamRespVo> processNodeExampleRunningParamRespVoList = processNodeExampleRunningParamMapper.selectListByRunningId(processNodeExampleRunningModel.getId());
            for (ProcessNodeExampleRunningParamRespVo data : processNodeExampleRunningParamRespVoList) {
                paramMap.put(data.getSendMethodParamName(), data.getSendMethodParamValue());
            }
        }*/
        processNodeExampleDetailsResp.setParamList(paramMap);
        processNodeExampleDetailsResp.setNodeParamList(nodeParamExampleRespVoList);
        return processNodeExampleDetailsResp;
    }

    @Override
    public List<NodeExampleStatusResp> getAllNodeExampleStatus(Long processExampleId) {
        List<NodeExampleStatusResp> nodeExampleStatusRespList = processNodeExampleMapper.selectListByProcessExampleIdAndNodeFlag(processExampleId);
        for (NodeExampleStatusResp nodeExampleStatusResp : nodeExampleStatusRespList) {
            Integer status = nodeExampleStatusResp.getStatus();
            String color = TaskStatusEnum.getColor(status);
            nodeExampleStatusResp.setColor(color);
        }
        return nodeExampleStatusRespList;
    }

    @Override
    public List<ProcessForNodeRespVo> getProcessForNodeInfo(Long parentId) {
        List<ProcessForNodeRespVo> processForNodeRespVoList = new ArrayList<>();
        List<ProcessNodeExampleModel> processNodeExampleModelList = processNodeExampleMapper.selectListByParentId(parentId);
        Map<Long, EquipmentRespVo> equipmentRespVoAllMap = equipmentService.getEquipmentRespVoAllMap();
        ProcessForNodeRespVo processForNodeRespVo;
        for (ProcessNodeExampleModel data : processNodeExampleModelList) {
            if (data.getNodeName().equals("start") || data.getNodeName().equals("end")) {
                continue;
            }
            processForNodeRespVo = new ProcessForNodeRespVo();
            processForNodeRespVo.setNodeName(data.getNodeName());
            processForNodeRespVo.setId(data.getId());
            processForNodeRespVo.setStatus(data.getStatus());
            Long equipmentId = data.getEquipmentId();
            if (equipmentId != null) {
                EquipmentRespVo equipmentRespVo = equipmentRespVoAllMap.get(equipmentId);
                if (equipmentRespVo != null) {
                    processForNodeRespVo.setImageUrl(equipmentRespVo.getImage());
                }
            }
            processForNodeRespVoList.add(processForNodeRespVo);
        }
        return processForNodeRespVoList;
    }

    @Override
    public void updateConfirmNodeFlag(Long id) {
        Map<String, ProcessNodeParamExampleModel> processNodeParam = processNodeParamExampleService.getProcessNodeParam(id);
        ProcessNodeParamExampleModel conditionValue = processNodeParam.get(NodeParamConstant.CONFIRM.conditionValue);
        conditionValue.setValue("1");
        processNodeParamExampleService.update(conditionValue);

    }

    // 异步执行节点
    private void asyncRunNode(ProcessNodeExampleModel processNodeExampleModel) {
        taskExecutor.execute(() -> {
            runNode(processNodeExampleModel);
        });

    }

    // 同步执行节点
    private void syncRunNode(ProcessNodeExampleModel processNodeExampleModel) {
        runNode(processNodeExampleModel);
    }

    // 运行某个节点
    public void runNode(ProcessNodeExampleModel processNodeExampleModel) {
        log.info("runNode,nodeId->{},nodeName:{}", processNodeExampleModel.getId(), processNodeExampleModel.getNodeName());
        // 如果处理了特殊情况的则不能往下继续执行
        boolean handle = handle(processNodeExampleModel);
        if (handle) {
            log.info("任务已经暂停或终止");
            return;
        }
        // 运行设备节点
        if (processNodeExampleModel.getEquipmentMethodTmpId() != null) {
            // 节点状态修改成运行中
            processNodeExampleService.updateNodeStatus(processNodeExampleModel.getId(), TaskStatusEnum.RUNNING.getStatus());
            runEquipmentNode(processNodeExampleModel);
        }
        // 结束节点
        if (processNodeExampleModel.getNodeName().equals(ProcessNodeNameEnum.END_NODE.getNodeName())) {
            // 节点状态修改成运行中
            processNodeExampleService.updateNodeStatus(processNodeExampleModel.getId(), TaskStatusEnum.RUNNING.getStatus());
            runEndNode(processNodeExampleModel);
        }
        // Delay节点
        if (processNodeExampleModel.getNodeName().equals(ProcessNodeNameEnum.DELAY.getNodeName())) {
            // 节点状态修改成运行中
            processNodeExampleService.updateNodeStatus(processNodeExampleModel.getId(), TaskStatusEnum.RUNNING.getStatus());
            runDelayNode(processNodeExampleModel);
        }
        // waitFor节点
        if (processNodeExampleModel.getNodeName().equals(ProcessNodeNameEnum.WAIT_FOR.getNodeName())) {
            // 节点状态修改成运行中
            processNodeExampleService.updateNodeStatus(processNodeExampleModel.getId(), TaskStatusEnum.RUNNING.getStatus());
            runWaitForNode(processNodeExampleModel);
        }
        // parallel(并行节点)
        if (processNodeExampleModel.getNodeName().equals(ProcessNodeNameEnum.PARALLEL_NODE.getNodeName())) {
            runParallelNode(processNodeExampleModel);
        }
        // setVariable节点
        if (processNodeExampleModel.getNodeName().equals(ProcessNodeNameEnum.SET_VARIABLE.getNodeName())) {
            runSetVariableNode(processNodeExampleModel);
        }

        // 运行condition节点
        if (processNodeExampleModel.getNodeName().equals(ProcessNodeNameEnum.CONDITION.getNodeName())) {
            runConditionNode(processNodeExampleModel);
        }

        // 运行processFor节点
        if (processNodeExampleModel.getNodeName().equals(ProcessNodeNameEnum.PROCESS_FOR.getNodeName())) {
            processNodeExampleService.updateNodeStatus(processNodeExampleModel.getId(), TaskStatusEnum.RUNNING.getStatus());
            runProcessForNode(processNodeExampleModel);
        }

        // 运行开始节点，兼容子流程里面的开始节点
        if (processNodeExampleModel.getNodeName().equals(ProcessNodeNameEnum.START_NODE.getNodeName())) {
            processNodeExampleService.updateNodeStatus(processNodeExampleModel.getId(), TaskStatusEnum.RUNNING.getStatus());
            runStartNode(processNodeExampleModel);
        }

        // 运行dataExt1节点
        if (processNodeExampleModel.getNodeName().equals(ProcessNodeNameEnum.DATA_EXT1.getNodeName())) {
            processNodeExampleService.updateNodeStatus(processNodeExampleModel.getId(), TaskStatusEnum.RUNNING.getStatus());
            runDataExt1(processNodeExampleModel);
        }

        // 运行自增/自减节点
        if (processNodeExampleModel.getNodeName().equals(ProcessNodeNameEnum.INCREMENT.getNodeName())) {
            processNodeExampleService.updateNodeStatus(processNodeExampleModel.getId(), TaskStatusEnum.RUNNING.getStatus());
            runIncrementNode(processNodeExampleModel);
        }
        // 运行setValue节点
        if (processNodeExampleModel.getNodeName().equals(ProcessNodeNameEnum.SET_VALUE.getNodeName())) {
            processNodeExampleService.updateNodeStatus(processNodeExampleModel.getId(), TaskStatusEnum.RUNNING.getStatus());
            runSetValue(processNodeExampleModel);
        }
        // 运行Confirm节点
        if (processNodeExampleModel.getNodeName().equals(ProcessNodeNameEnum.CONFIRM.getNodeName())) {
            processNodeExampleService.updateNodeStatus(processNodeExampleModel.getId(), TaskStatusEnum.RUNNING.getStatus());
            runConfirmNode(processNodeExampleModel);
        }


    }

    private void runStartNode(ProcessNodeExampleModel processNodeExampleModel) {
        Long processNodeExampleModelId = processNodeExampleModel.getId();
        log.info("runStartNode_NodeId:{}", processNodeExampleModelId);
        // 直接改成已完成状态，执行下个节点
        processNodeExampleService.updateNodeStatus(processNodeExampleModel.getId(), TaskStatusEnum.SUCCESS.getStatus());
        if (processNodeExampleModel.getParentId() != null) {
            runNextNode(processNodeExampleModelId);
        }
    }

    private void runEquipmentNode(ProcessNodeExampleModel processNodeExampleModel) {
        long startTime = System.currentTimeMillis();
        ProcessNodeExampleRunningModel processNodeExampleRunningModel = processNodeExampleRunningService.add(processNodeExampleModel.getId());
        processNodeExampleRunningService.sendCommand(processNodeExampleRunningModel.getId());
        long endTime = System.currentTimeMillis();
        log.info("runEquipmentNode,nodeId:{}->{}，runEquipmentNodeTime:{}毫秒", processNodeExampleModel.getId(),
                processNodeExampleModel.getNodeName(), (endTime - startTime));
    }


    private void runParallelNode(ProcessNodeExampleModel processNodeExampleModel) {
        Long id = processNodeExampleModel.getId();
        Long processExampleId = processNodeExampleModel.getProcessExampleId();
        String targetNodeId = processNodeExampleModel.getTargetNodeId();

        Map<String, ProcessNodeParamExampleModel> processNodeParam = processNodeParamExampleService.getProcessNodeParam(id);
        ProcessNodeParamExampleModel processNodeParamExampleModel = processNodeParam.get("nodeFlag");

        //ProcessNodeParamExampleModel processNodeParamExampleModel = JSONObject.parseObject(JSONObject.toJSONString(nodeFlagObj), ProcessNodeParamExampleModel.class);
        ProcessNodeExampleModel processNodeExampleModel1 = processNodeExampleMapper.selectListBySourceNodeIdAndProcessExampleId(targetNodeId, processExampleId).get(0);
        String nodeFlag = processNodeParamExampleModel.getValue();

        // 如果是并行开始节点，查找此节点targetNodeId直接异步执行
        if (nodeFlag.equals("start")) {
            log.info("并行网关开始");
            log.info("processNodeExampleModel1:{}", JSONObject.toJSONString(processNodeExampleModel1));
            updateNodeStatus(id, TaskStatusEnum.RUNNING.getStatus());
            updateNodeStatus(id, TaskStatusEnum.SUCCESS.getStatus());
            runNode(processNodeExampleModel1);
        }
        // 如果是并行结束节点，要判断每条线是否都执行完毕，如果都执行完毕则可以继续执行
        if (nodeFlag.equals("end")) {
            Object nodeIdObj = processNodeParam.get("id");
            ProcessNodeParamExampleModel nodeIdModel = JSONObject.parseObject(JSONObject.toJSONString(nodeIdObj), ProcessNodeParamExampleModel.class);
            String nodeId = nodeIdModel.getValue();
            if (processNodeExampleModel.getParentId() != null) {
                String suffix = processNodeExampleModel.getSourceNodeId().split("_")[1];
                nodeId = nodeId + "_" + suffix;
            }
            int size = processNodeExampleMapper.selectListBySourceNodeIdAndProcessExampleId(nodeId, processExampleId).size();
            String mapKey = CommonUtils.getParallelNodeMapKey(processNodeExampleModel);
            Integer currentSize = temporaryMapService.getInt(mapKey);
            log.info("totalSize:{},currentSize start:{}", size, currentSize);
            if (currentSize == null) {
                currentSize = 1;
                temporaryMapService.setInt(mapKey, currentSize);
            } else {
                currentSize = currentSize + 1;
                temporaryMapService.setInt(mapKey, currentSize);
            }
            log.info("处理完后totalSize:{},currentSize end:{}", size, currentSize);
            if (size == currentSize) {
                log.info("并行网关结束");
                updateNodeStatus(id, TaskStatusEnum.RUNNING.getStatus());
                updateNodeStatus(id, TaskStatusEnum.SUCCESS.getStatus());
                runNextNode(id);
            }
        }
    }

    private void runEndNode(ProcessNodeExampleModel processNodeExampleModel) {
        Long processNodeExampleModelId = processNodeExampleModel.getId();
        log.info("runEndNode_nodeId:{}", processNodeExampleModelId);
        // 将结束节点状态变成已完成
        updateNodeStatus(processNodeExampleModelId, TaskStatusEnum.SUCCESS.getStatus());

        // processFor是特殊节点，特殊的结束节点直接运行下一个节点
        if (processNodeExampleModel.getParentId() != null) {
            runNextNode(processNodeExampleModel.getId());
            return;
        }

        // 当前结束节点的流程状态变成已完成
        processExampleService.updateStatus(processNodeExampleModel.getProcessExampleId(), TaskStatusEnum.SUCCESS.getStatus());

        // 运行下一个普通流程
        Boolean isRunNextProcessExample = processExampleService.runNextProcessExample(processNodeExampleModelId);
        if (isRunNextProcessExample) {
            return;
        } else {
            // 没找到下一个普通流程则代表是最后一个流程了，把改节点的上级子任务状态改成已完成
            subTaskExampleService.updateStatusByNodeId(processNodeExampleModelId, TaskStatusEnum.SUCCESS.getStatus());
        }
        // 运行子任务
        Boolean isRunNextSubTaskExample = subTaskExampleService.runNextSubTaskExample(processNodeExampleModelId);
        if (isRunNextSubTaskExample) {
            return;
        }
        // 运行结束流程
        Boolean isRunEndProcessExample = processExampleService.runEndProcessExample(processNodeExampleModelId);
        if (!isRunEndProcessExample) {
            // 找不到结束，则将任务实例变成已完成
            log.info("任务运行完毕！");
            ProcessNodeExampleModel processNodeExampleModel1 = processNodeExampleMapper.selectById(processNodeExampleModelId);
            ProcessExampleModel processExampleModel = processExampleService.getById(processNodeExampleModel1.getProcessExampleId());
            Long taskExampleId = processExampleModel.getTaskExampleId();

            // 任务状态更新成已完成
            taskExampleService.updateStatus(taskExampleId, TaskStatusEnum.SUCCESS.getStatus());
            // 记录运行日志
            TaskExampleModel taskExampleModel = taskExampleService.getById(taskExampleId);
            messageNoticeRecordService.add(taskExampleModel.getName() + "-运行完毕！");
            // 回传样样本数据
            //sampleService.callBackSample(taskExampleId);
        }
    }

    private Boolean runSelectNode(ProcessNodeExampleModel processNodeExampleModel) {
        return true;
    }

    private Boolean runLoopNode(ProcessNodeExampleModel processNodeExampleModel) {
        return true;
    }

    private void runDelayNode(ProcessNodeExampleModel processNodeExampleModel) {
        log.info("运行Delay节点");
        // 放入到待执行队列
        pendingNodeQueueService.add(processNodeExampleModel.getId());
    }

    private void runWaitForNode(ProcessNodeExampleModel processNodeExampleModel) {
        log.info("运行WaitFor节点");
        // 放入到待执行队列
        pendingNodeQueueService.add(processNodeExampleModel.getId());
    }

    private void runSetVariableNode(ProcessNodeExampleModel processNodeExampleModel) {
        Long processNodeExampleModelId = processNodeExampleModel.getId();
        log.info("运行SetVariableNode节点");
        Map<String, ProcessNodeParamExampleModel> processNodeParam = processNodeParamExampleService.getProcessNodeParam(processNodeExampleModel.getId());
        ProcessNodeParamExampleModel conditionVariableValue = processNodeParam.get("conditionVariable");
        ProcessNodeParamExampleModel conditionValueValue = processNodeParam.get("conditionValue");
        log.info("conditionVariableValue:{},conditionValueValue:{}", conditionVariableValue, conditionValueValue);
        VariableExampleModel variableExampleModel = variableExampleService.getByName(processNodeExampleModel.getId(), conditionVariableValue.getValue());
        variableExampleService.setVariableValueById(variableExampleModel.getId(), conditionValueValue.getValue(), false);
        updateNodeStatus(processNodeExampleModelId, TaskStatusEnum.SUCCESS.getStatus());
        runNextNode(processNodeExampleModel.getId());
    }

    private void runConditionNode(ProcessNodeExampleModel processNodeExampleModel) {
        log.info("运行runConditionNode节点");
        Map<String, ProcessNodeParamExampleModel> processNodeParam = processNodeParamExampleService.getProcessNodeParam(processNodeExampleModel.getId());
        ProcessNodeParamExampleModel conditionVariable = processNodeParam.get(NodeParamConstant.CONDITION.conditionVariable);
        ProcessNodeParamExampleModel conditionExpress = processNodeParam.get(NodeParamConstant.CONDITION.conditionExpress);
        ProcessNodeParamExampleModel conditionValue = processNodeParam.get(NodeParamConstant.CONDITION.conditionValue);
        boolean isOk = runConditionNodeFlag(conditionVariable, conditionExpress, conditionValue);
        log.info("conditionVariableValue:{},conditionExpressValue:{},conditionExpressValue:{},isOk:{}"
                , conditionVariable.getValue(), conditionExpress.getValue(), conditionValue.getValue(), isOk);
        List<ProcessNodeExampleModel> nextNodeList = getNextNodes(processNodeExampleModel.getId());
        log.info("runConditionNode_nextNodeList:\n{}->{}", processNodeExampleModel.getId(), JSONObject.toJSONString(nextNodeList));
        for (ProcessNodeExampleModel nextNode : nextNodeList) {
            // 运行满足条件的ConditionNode
            if (isOk) {
                log.info("Condition满足条件:{}", conditionValue.getValue());
                // 当前ConditionNode节点状态修改为已完成状态
                processNodeExampleService.updateNodeStatus(processNodeExampleModel.getId(), TaskStatusEnum.SUCCESS.getStatus());
                // 运行ConditionNode下一个节点信息
                asyncRunNode(nextNode);
            } else {
                log.info("Condition未满足条件:{}", conditionValue.getValue());
                // 当前ConditionNode节点状态修改为跳过状态
                processNodeExampleService.updateNodeStatus(processNodeExampleModel.getId(), TaskStatusEnum.SKIP.getStatus());
                // 下一个节点直到并行网关结束节点状态都改成跳过,网关end则跳出循环。
                //processNodeExampleService.updateNodeStatus(nextNode.getId(), TaskStatusEnum.SKIP.getStatus());

                boolean isRun = true;
                List<ProcessNodeExampleModel> nextNodeList2 = new ArrayList<>();
                nextNodeList2.add(nextNode);
                while (isRun) {
                    ProcessNodeExampleModel runNodeExampleModel = nextNodeList2.get(0);
                    if (runNodeExampleModel == null) {
                        continue;
                    }
                    Map<String, ProcessNodeParamExampleModel> processNodeParam1 = processNodeParamExampleService.getProcessNodeParam(runNodeExampleModel.getId());
                    ProcessNodeParamExampleModel processNodeParamExampleModel = processNodeParam1.get("nodeFlag");
                    if (processNodeParamExampleModel != null && processNodeParamExampleModel.getValue().equals("end")) {
                        isRun = false;
                        // 运行一下并行网关的结束节点
                        runParallelNode(runNodeExampleModel);
                    } else {
                        //log.info("updateStatus:{}", JSONObject.toJSONString(runNodeExampleModel));
                        processNodeExampleService.updateNodeStatus(runNodeExampleModel.getId(), TaskStatusEnum.SKIP.getStatus());
                    }
                    // 获取下一个节点信息
                    nextNodeList2.clear();
                    nextNodeList2 = getNextNodes(runNodeExampleModel.getId());
                }
            }
        }
    }


    // 运行processFor节点
    private void runProcessForNode(ProcessNodeExampleModel processNodeExampleModel) {
        Long processNodeExampleModelId = processNodeExampleModel.getId();
        log.info("runProcessForNode_nodeId:{}", processNodeExampleModelId);
        // 将结束节点状态变成已完成
        updateNodeStatus(processNodeExampleModelId, TaskStatusEnum.SUCCESS.getStatus());
        runNextNode(processNodeExampleModel.getId());
    }

    private void runIncrementNode(ProcessNodeExampleModel processNodeExampleModel) {
        log.info("运行runConditionNode节点");
        Map<String, ProcessNodeParamExampleModel> processNodeParam = processNodeParamExampleService.getProcessNodeParam(processNodeExampleModel.getId());
        ProcessNodeParamExampleModel conditionVariable = processNodeParam.get(NodeParamConstant.INCREMENT.conditionVariable);
        ProcessNodeParamExampleModel symbols = processNodeParam.get(NodeParamConstant.INCREMENT.symbols);
        ProcessNodeParamExampleModel conditionValue = processNodeParam.get(NodeParamConstant.INCREMENT.conditionValue);

        String conditionVariableStr = conditionVariable.getValue();
        String symbolsStr = symbols.getValue();
        String conditionValueStr = conditionValue.getValue();

        VariableExampleModel variableExampleModel = variableExampleService.getByName(processNodeExampleModel.getId(), conditionVariableStr);
        String variableExampleStr = variableExampleModel.getValue();
        int variableValue = Integer.parseInt(variableExampleStr);
        int conditionValueValue = Integer.parseInt(conditionValueStr);
        if (symbolsStr.equals("+")) {
            variableValue = variableValue + conditionValueValue;
        }

        if (symbolsStr.equals("-")) {
            variableValue = variableValue - conditionValueValue;
        }
        variableExampleService.setVariableValueById(variableExampleModel.getId(), variableValue + "", false);
        processNodeExampleService.updateNodeStatus(processNodeExampleModel.getId(), TaskStatusEnum.SUCCESS.getStatus());
        runNextNode(processNodeExampleModel.getId());
    }

    private Boolean runSetPrefixNode(ProcessNodeExampleModel processNodeExampleModel) {
        return true;
    }

    private Boolean runSetSuffixNode(ProcessNodeExampleModel processNodeExampleModel) {
        return true;
    }

    public void runDataExt1(ProcessNodeExampleModel processNodeExampleModel) {
        Long processNodeExampleId = processNodeExampleModel.getId();
        Map<String, ProcessNodeParamExampleModel> processNodeParamExampleModelMap = processNodeParamExampleService.getProcessNodeParam(processNodeExampleId);
        ProcessNodeParamExampleModel conditionVariable = processNodeParamExampleModelMap.get(NodeParamConstant.DATA_EXT1.conditionVariable);
        ProcessNodeParamExampleModel conditionValue = processNodeParamExampleModelMap.get(NodeParamConstant.DATA_EXT1.conditionValue);
        ProcessNodeParamExampleModel outPutVariable = processNodeParamExampleModelMap.get(NodeParamConstant.DATA_EXT1.outPutVariable);

        String conditionVariableStr = conditionVariable.getValue();

        String conditionValueStr = conditionValue.getValue();
        String outPutVariableStr = outPutVariable.getValue();

        List<Object> dataList = new ArrayList<>();
        /// 因为此节点是运行中区执行，所以要查询变量实例
        VariableExampleModel conditionVariableValue = variableExampleService.getByName(processNodeExampleModel.getId(), conditionVariableStr);
        String paramType = conditionVariableValue.getValueType();
        String value = conditionVariableValue.getValue();

        if (paramType.equals(MethodParamTypeEnum.ARRAY.getType())) {
            VariableExampleModel conditionVariableMode = variableExampleService.getByName(processNodeExampleId, conditionVariableStr);
            String conditionVariableModeValueStr = conditionVariableMode.getValue();
            dataList = JSONObject.parseArray(conditionVariableModeValueStr, Object.class);
        }

        if (paramType.equals(MethodParamTypeEnum.INT.getType())) {
            int count = Integer.parseInt(value);
            for (int i = 1; i <= count; i++) {
                dataList.add(i);
            }
        }

        JSONArray jsonArray = new JSONArray();
        for (int i = 0; i < dataList.size(); i++) {
            JSONObject jsonObject = new JSONObject();
            Object data = dataList.get(i);
            List<DataExt1Vo> dataExt1List = JSONObject.parseArray(conditionValueStr, DataExt1Vo.class);
            for (DataExt1Vo dataExt1Vo : dataExt1List) {
                String fileName = dataExt1Vo.getFileName();
                Integer fileValueType = dataExt1Vo.getFileValueType();
                String fileValue = dataExt1Vo.getFileValue();

                String jsonObjectValue = "";
                // 0数组变量，1固定值，2数字自增，3前缀+数字自增，4前缀+数组变量
                if (fileValueType == 0) {
                    log.info("runDataExt1 fileName:{}, fileValueType:{}, fileValue:{}", fileName, fileValueType, fileValue);
                    VariableExampleValueResp variableModel = variableExampleService.getByNameExt(processNodeExampleId, fileValue);
                    jsonObjectValue = variableModel.getCurrentValue();
                }
                if (fileValueType == 1) {
                    jsonObjectValue = fileValue;
                }
                if (fileValueType == 2) {
                    int fileValueInt = Integer.parseInt(fileValue);
                    fileValueInt = fileValueInt + i;
                    jsonObjectValue = fileValueInt + "";
                }
                if (fileValueType == 3) {
                    jsonObjectValue = fileValue + (i + 1);
                }
                if (fileValueType == 4) {
                    jsonObjectValue = fileValue + data.toString();
                }
                jsonObject.put(fileName, jsonObjectValue);
            }
            jsonArray.add(jsonObject);
        }
        VariableExampleModel outPutVariableModel = variableExampleService.getByName(processNodeExampleId, outPutVariableStr);
        String outPutVariableJsonStr = JSONObject.toJSONString(jsonArray);
        log.info("runDataExt1生成的数据：{}", outPutVariableJsonStr);
        variableExampleService.setVariableValueById(outPutVariableModel.getId(), outPutVariableJsonStr, true);
        processNodeExampleService.updateNodeStatus(processNodeExampleModel.getId(), TaskStatusEnum.SUCCESS.getStatus());
        runNextNode(processNodeExampleModel.getId());
    }

    private void runConfirmNode(ProcessNodeExampleModel processNodeExampleModel) {
        log.info("运行confirm节点");
        // 放入到待执行队列
        pendingNodeQueueService.add(processNodeExampleModel.getId());
    }

    /**
     * 执行setValue节点，此节点不看变量值类型直接赋值
     */
    private void runSetValue(ProcessNodeExampleModel processNodeExampleModel) {
        Long processNodeExampleModelId = processNodeExampleModel.getId();
        log.info("运行runSetValue节点,processNodeExampleModelId:{}", processNodeExampleModelId);
        Map<String, ProcessNodeParamExampleModel> processNodeParam = processNodeParamExampleService.getProcessNodeParam(processNodeExampleModel.getId());
        ProcessNodeParamExampleModel conditionVariableValue = processNodeParam.get("conditionVariable");
        ProcessNodeParamExampleModel conditionValueValue = processNodeParam.get("conditionValue");
        log.info("conditionVariableValue:{},conditionValueValue:{}", conditionVariableValue, conditionValueValue);
        VariableExampleModel variableExampleModel = variableExampleService.getByName(processNodeExampleModel.getId(), conditionVariableValue.getValue());
        variableExampleService.setVariableValueById(variableExampleModel.getId(), conditionValueValue.getValue(), true);
        updateNodeStatus(processNodeExampleModelId, TaskStatusEnum.SUCCESS.getStatus());
        runNextNode(processNodeExampleModel.getId());
    }


    private List<ProcessNodeExampleModel> getNextNodes(Long processNodeExampleId) {
        //  查询当前节点信息
        ProcessNodeExampleModel processNodeExampleModel = processNodeExampleMapper.selectById(processNodeExampleId);
        // 查询当前节点下面一批节点信息
        QueryWrapper<ProcessNodeExampleModel> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(ProcessNodeExampleModel.PROCESS_EXAMPLE_ID, processNodeExampleModel.getProcessExampleId());
        queryWrapper.eq(ProcessNodeExampleModel.SOURCE_NODE_ID, processNodeExampleModel.getTargetNodeId());
        queryWrapper.eq(ProcessNodeExampleModel.STATUS, TaskStatusEnum.READY.getStatus());
        return processNodeExampleMapper.selectList(queryWrapper);
    }


    /**
     * 节点状态是暂停中则让此节点变成已暂停
     * 节点状态是停止中则让此节点变成已停止
     *
     * @param processNodeExampleModel
     * @return
     */
    private boolean handle(ProcessNodeExampleModel processNodeExampleModel) {
        boolean isHandel = false;
        // 以下节点类型不暂停或者停止
        if (processNodeExampleModel.getNodeName().equals(ProcessNodeNameEnum.PARALLEL_NODE.getNodeName())) {
            return isHandel;
        }

        Long processNodeExampleId = processNodeExampleModel.getId();
        Long processExampleId = processNodeExampleModel.getProcessExampleId();
        ProcessNodeExampleInfoExt processNodeExampleModelExt = getProcessNodeExampleModelExt(processNodeExampleId);
        Long taskExampleId = processNodeExampleModelExt.getProcessExampleModel().getTaskExampleId();
        TaskExampleModel taskExampleModel = taskExampleService.getById(taskExampleId);
        int status = TaskStatusEnum.READY.getStatus();

        if (taskExampleModel.getStatus() == TaskStatusEnum.PAUSING.getStatus()) {
            isHandel = true;
            status = TaskStatusEnum.PAUSED.getStatus();
        }
        if (taskExampleModel.getStatus() == TaskStatusEnum.PAUSED.getStatus()) {
            isHandel = true;
            status = TaskStatusEnum.PAUSED.getStatus();
        }

        if (taskExampleModel.getStatus() == TaskStatusEnum.STOPPING.getStatus()) {
            status = TaskStatusEnum.STOP.getStatus();
            isHandel = true;
        }
        if (taskExampleModel.getStatus() == TaskStatusEnum.STOP.getStatus()) {
            status = TaskStatusEnum.STOP.getStatus();
            isHandel = true;
        }

        if (isHandel) {
            // 修改节点状态
            updateNodeStatus(processNodeExampleId, status);
            // 修改流程状态
            processExampleService.updateStatus(processExampleId, status);
            // 修改子任务状态
            subTaskExampleService.updateStatusByNodeId(processNodeExampleId, status);
            // 修改任务状态
            taskExampleService.updateStatus(taskExampleId, status);
        }
        return isHandel;
    }

    /**
     * 计算条件是否通过如果未通过节点状态都改成跳过一直到结束节点
     *
     * @return
     */
    private boolean runConditionNodeFlag(ProcessNodeParamExampleModel conditionVariable, ProcessNodeParamExampleModel conditionExpress, ProcessNodeParamExampleModel conditionValue) {
        String conditionVariableValue = conditionVariable.getValue();
        String conditionExpressValue = conditionExpress.getValue();
        String conditionValueValueStr = conditionValue.getValue();

        VariableExampleModel variableExampleModel = variableExampleService.getByName(conditionExpress.getProcessNodeExampleId(), conditionVariableValue);
        String variableExampleStr = variableExampleModel.getValue();
        int variableValue = Integer.parseInt(variableExampleStr);
        int conditionValueValue = Integer.parseInt(conditionValueValueStr);
        // 条件 > < ≥ ≤ = ≠
        return switch (conditionExpressValue) {
            case ">" -> variableValue > conditionValueValue;
            case "<" -> variableValue < conditionValueValue;
            case "≥" -> variableValue >= conditionValueValue;
            case "≤" -> variableValue <= conditionValueValue;
            case "=" -> variableValue == conditionValueValue;
            case "≠" -> variableValue != conditionValueValue;
            default -> false;
        };
    }

}
